import { Component, game, _decorator } from 'cc'
import { DIRECTION_ENUM, EVENT_NAME_ENUM } from '../enums'
import EventMgr from '../runtime/EventMgr'
const { ccclass } = _decorator

@ccclass('ShakeMgr')
export class ShakeMgr extends Component {
  private isShaking = false // 是否正在震动
  private oldTime: number = 0 // 开始震动的时间
  private oldPos: { x: number; y: number } = { x: 0, y: 0 }
  private shakeType: DIRECTION_ENUM = DIRECTION_ENUM.TOP

  onLoad() {
    EventMgr.Instance.on(EVENT_NAME_ENUM.SCREEN_SHAKE, this.shake, this)
  }

  shake(direction: DIRECTION_ENUM) {
    if (this.isShaking) return
    this.isShaking = true
    this.shakeType = direction
    this.oldTime = game.totalTime // 存储开始震动的时间
    this.oldPos.x = this.node.position.x // 存储当前节点的旧位置
    this.oldPos.y = this.node.position.y // 存储当前节点的旧位置
  }

  /** 停止震动 */
  stop() {
    this.isShaking = false
  }

  update(dt: number): void {
    // 偏移的计算公式 Y = a * sin(ωt + f) a表示振幅，ω表示频率，t表示时间，f表示时间
    if (this.isShaking) {
      const duration = 500 // 震动持续时间
      const a = 2
      const w = 10
      const curSecond = (game.totalTime - this.oldTime) / 1000 // 当前时间间隔秒数
      const totalSecond = duration / 1000 // 震动时间
      const offset = a * Math.sin(w * Math.PI * curSecond) // 偏移量
      if (this.shakeType === DIRECTION_ENUM.TOP) {
        this.node.setPosition(this.oldPos.x, this.oldPos.y + offset)
      } else if (this.shakeType === DIRECTION_ENUM.BOTTOM) {
        this.node.setPosition(this.oldPos.x, this.oldPos.y - offset)
      } else if (this.shakeType === DIRECTION_ENUM.LEFT) {
        this.node.setPosition(this.oldPos.x - offset, this.oldPos.y)
      } else if (this.shakeType === DIRECTION_ENUM.RIGHT) {
        this.node.setPosition(this.oldPos.x + offset, this.oldPos.y)
      } else if (this.shakeType === DIRECTION_ENUM.TURNLEFT || this.shakeType === DIRECTION_ENUM.TURNRIGHT) {
        this.node.setPosition(this.oldPos.x - offset, this.oldPos.y + offset)
      }
      if (curSecond > totalSecond) {
        this.isShaking = false
        this.node.setPosition(this.oldPos.x, this.oldPos.y) // 复位
      }
    }
  }

  onDestroy(): void {
    EventMgr.Instance.off(EVENT_NAME_ENUM.SCREEN_SHAKE, this.shake)
  }
}
